﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Spire.Xls;
using YanTableManger.TableData;

namespace YanTableManger
{
    public partial class Frm_Main : Form
    {
        private readonly string _desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
        private readonly string _filePath = "";
        private const string DirName = "~$%补贴明细%$~";

        public Frm_Main()
        {
            InitializeComponent();
            ExcelManager.Close();
            _filePath = $@"{_desktopPath}\{DirName}";
            lab_q_path.Text = $"文件目录【{DirName}】";
        }

        private void btn_chooseFile_Click(object sender, EventArgs e)
        {
            var fileNames = ChooseMultiFile("请选择校车统计表");
            foreach (var name in fileNames)
            {
                list_s_files.Items.Add(name);
            }

            if (list_s_files.Items.Count == 0) return;
            btn_s_path.Enabled = true;
            btn_s_clearFiles.Enabled = true;
            btn_s_generate.Enabled = true;
        }


        private void btn_s_generate_Click(object sender, EventArgs e)
        {
            try
            {
                var users = new Dictionary<string, STableData>();
                if (list_s_files.Items.Count == 0) throw new Exception("没有选择任何文件！请选择文件后在执行此操作！");
                if (txt_s_path.Text.Length == 0 || txt_s_name.Text.Length == 0)
                {
                    throw new Exception("未选择文件保存位置");
                }
                else if (!Directory.Exists(txt_s_path.Text))
                {
                    throw new Exception("将要保存结果的文件夹不存在！请重新选择文件夹！");
                }

                btn_s_generate.Enabled = false;
                btn_s_chooseFile.Enabled = false;
                btn_s_clearFiles.Enabled = false;
                btn_s_path.Enabled = false;

                foreach (var fileItem in list_s_files.Items)
                {
                    ReadSUserData(fileItem.ToString(), users);
                }

                WriteSUserData($@"{txt_s_path.Text}\{txt_s_name.Text}.xlsx", users);

                Log("车贴统计完成...");
                btn_s_chooseFile.Enabled = true;
                list_s_files.Items.Clear();
                txt_s_path.Text = _desktopPath;
                btn_s_clearFiles.Enabled = false;
                ofd.Reset();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Log("任务异常中断");
            }
            finally
            {
                ExcelManager.Close();
            }
        }

        /// <summary>
        /// 将校车统计表写入文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="users"></param>
        private void WriteSUserData(string fileName, Dictionary<string, STableData> users)
        {
            var manager = new ExcelManager();

            Log($"开始创建工作簿“{fileName}");
            manager.CreateWorkbook();
            //设置表头
            var cells = new List<Cell>()
            {
                new Cell(1, 1, "工号"),
                new Cell(1, 2, "姓名"),
                new Cell(1, 3, "金额")
            };
            manager.SetCells(cells);

            var lister = users.Values.ToList();
            var data = lister.Select(user => user.ToList()).ToList();

            Log("开始写入数据,请耐心等待...");
            manager.SetRows(2, data);
            manager.SetColumnWidth(1, 20);

            Log("写入数据成功...");

            manager.SaveCopyAs(fileName);
            Log("保存工作簿...");
            manager.CloseWorkbook();
            Log("关闭工作簿...");
            ExcelManager.Close();
        }

        /// <summary>
        /// 设置校车统计数据
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="users"></param>
        private void ReadSUserData(string fileName, Dictionary<string, STableData> users)
        {
            ExcelManager manager = new ExcelManager();

            manager.OpenWorkbook(fileName);
            Log($"打开工作簿“{fileName}”...");
            manager.OpenWorksheet("软件学院流水");
            Log("打开工作表...");

            Log("开始读取数据，请耐心等待...");
            for (int i = 2; i <= manager.GetWorkSheetRowsCount(); i++)
            {
                var id = manager.GetData("A" + i);
                var name = manager.GetData("B" + i);
                var money = -Convert.ToInt32(manager.GetData("E" + i));

                if (users.ContainsKey(id))
                {
                    users[id].Money += money;
                }
                else
                {
                    users.Add(id, new STableData(id, name, money));
                }
            }

            Log("读取数据完成....");
            manager.CloseWorkbook();
            Log("关闭工作簿...");
            ExcelManager.Close();
        }

        /// <summary>
        /// 设置新校区考勤数据
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="users"></param>
        private void ReadNewKUserData(string fileName, Dictionary<string, KTableData> users)
        {
            ExcelManager manager = new ExcelManager();
            Log("开始统计新校区考勤统计，统计过程中请务必不要对原文件做任何操作");
            manager.OpenWorkbook(fileName);
            Log($"打开工作簿【{fileName}】...");
            manager.OpenWorksheet("打卡明细表");
            Log("打开工作表...");
            Log("正在读取数据，请耐心等待...");

            const int nameCol = 1;
            const int initRow = 3;
            const int dakaCol = 4;

            var cells = manager.GetAllData();
            //按行处理
            for (var i = initRow; i < cells.Length; i++)
            {
                //名字
                var name = cells[i][nameCol];
                //打卡次数
                int hitCount = 0;

                //用户已经被创建
                if (users.ContainsKey(name))
                {
                    for (int j = dakaCol; j < cells[i].Length; j++)
                    {
                        //如果n,j单元格没有值，直接跳过
                        if (cells[i][j] == null || cells[i][j].Length <= 4) continue;
                        //如果设置了新校区优先
                        if (ckb_k_key.Checked)
                        {
                            users[name].HitCards[j - dakaCol] = HitCard.New;
                            hitCount++;
                        }
                        else
                        {
                            if (users[name].HitCards[j - dakaCol] == HitCard.None)
                            {
                                users[name].HitCards[j - dakaCol] = HitCard.New;
                                hitCount++;
                            }
                        }
                    }
                }
                else
                {
                    KTableData user = new KTableData()
                    {
                        Name = name
                    };
                    for (int j = dakaCol; j < cells[i].Length; j++)
                    {
                        //如果没有值设置为none
                        if (cells[i][j] == null || cells[i][j].Length <= 4)
                        {
                            user.HitCards[j - dakaCol] = HitCard.None;
                        }
                        else
                        {
                            //如果有值，因为新创建，所以直接赋值为新校区
                            user.HitCards[j - dakaCol] = HitCard.New;
                            hitCount++;
                        }
                    }

                    users.Add(name, user);
                }

                Log($"【{name}】在新校区打卡【{hitCount}】次");
            }

            manager.CloseWorkbook();
            Log("新校区考勤统计完成...");
            ExcelManager.Close();
        }

        /// <summary>
        /// 设置老校区考勤数据
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="users"></param>
        private void ReadOldKUserData(string fileName, Dictionary<string, KTableData> users)
        {
            ExcelManager manager = new ExcelManager();
            Log("开始统计老校区考勤统计，统计过程中请务必不要对原文件做任何操作");
            manager.OpenWorkbook(fileName);
            Log($"打开工作簿【{fileName}】");
            manager.OpenWorksheet("考勤记录");
            Log("打开工作表...");
            Log("正在读取数据，请耐心等待...");

            const int idCol = 2;
            const int nameCol = 10;
            const int initRow = 4;

            var cells = manager.GetAllData();
            //按行处理
            for (var i = initRow; i < cells.Length; i += 2)
            {
                //姓名行号下一列
                var n = i + 1;
                //id
                var id = cells[i][idCol];
                //名字
                var name = cells[i][nameCol];
                //打卡次数
                int hitCount = 0;


                if (users.ContainsKey(name))
                {
                    for (int j = 0; j < cells[n].Length; j++)
                    {
                        //如果n,j单元格没有值，直接跳过
                        if (cells[n][j] == null || cells[n][j].Length <= 4) continue;
                        //如果设置了老校区优先
                        if (!ckb_k_key.Checked)
                        {
                            users[name].HitCards[j] = HitCard.Old;
                            hitCount++;
                        }
                        else
                        {
                            if (users[name].HitCards[j] == HitCard.None)
                            {
                                users[name].HitCards[j] = HitCard.Old;
                                hitCount++;
                            }
                        }
                    }
                }
                else
                {
                    KTableData user = new KTableData()
                    {
                        Id = id,
                        Name = name
                    };
                    for (int j = 0; j < cells[i].Length; j++)
                    {
                        //如果没有值设置为none
                        if (cells[n][j] == null || cells[n][j].Length <= 4)
                        {
                            user.HitCards[j] = HitCard.None;
                        }
                        else
                        {
                            //如果有值，因为新创建，所以直接赋值为老校区
                            user.HitCards[j] = HitCard.Old;
                            hitCount++;
                        }
                    }

                    users.Add(name, user);
                }

                Log($"【{name}】在老校区打卡【{hitCount}】次");
            }

            manager.CloseWorkbook();
            Log("老校区考勤统计完成...");
            ExcelManager.Close();
        }

        private void Log(string text)
        {
            rtx_logs.AppendText(DateTime.Now.ToString("[hh:mm:ss]:") + text + "\n");
            rtx_logs.ScrollToCaret();
        }

        private void btn_s_clearFiles_Click(object sender, EventArgs e)
        {
            list_s_files.Items.Clear();
            btn_s_generate.Enabled = false;
            btn_s_clearFiles.Enabled = false;
            btn_s_path.Enabled = false;
        }

        private string[] ChooseMultiFile(string title)
        {
            ofd.Reset();
            ofd.Title = title;
            ofd.Filter = @"excel文件|*.xls;*.xlsx";
            ofd.Multiselect = true;
            ofd.ShowDialog();
            return ofd.FileNames;
        }

        private string ChooseSingleFile(string title)
        {
            ofd.Reset();
            ofd.Title = title;
            ofd.Filter = @"excel文件|*.xls;*.xlsx";
            ofd.Multiselect = false;
            ofd.ShowDialog();
            return ofd.FileName;
        }

        private string ChoosePath()
        {
            fbd.Reset();
            fbd.ShowNewFolderButton = true;
            fbd.RootFolder = Environment.SpecialFolder.MyComputer;
            fbd.ShowDialog();
            return fbd.SelectedPath;
        }

        private void btn_s_path_Click(object sender, EventArgs e)
        {
            var path = ChoosePath();
            if (path.Length > 0)
            {
                txt_s_path.Text = path;
            }
        }

        private void btn_clearLog_Click(object sender, EventArgs e)
        {
            rtx_logs.Text = "";
        }

        private void ckb_k_key_CheckedChanged(object sender, EventArgs e)
        {
            nb_k_new.Enabled = !nb_k_new.Enabled;
            nb_k_old.Enabled = !nb_k_old.Enabled;
            nb_q_new.Enabled = nb_k_new.Enabled;
            nb_q_old.Enabled = nb_k_old.Enabled;
            ckb_q_key.Checked = ckb_k_key.Checked;
        }

        private void btn_k_new_Click(object sender, EventArgs e)
        {
            var path = ChooseSingleFile("请选择新校区考勤表");
            if (path.Length > 0)
            {
                txt_k_new.Text = path;
            }

            if (txt_k_old.Text.Length <= 0 || txt_k_new.Text.Length <= 0) return;
            btn_k_path.Enabled = true;
            if (lab_k_path.Text.Length > 0)
            {
                btn_k_generate.Enabled = true;
            }
        }

        private void btn_k_old_Click(object sender, EventArgs e)
        {
            var path = ChooseSingleFile("请选择老校区考勤表");
            if (path.Length > 0)
            {
                txt_k_old.Text = path;
            }

            if (txt_k_old.Text.Length <= 0 || txt_k_new.Text.Length <= 0) return;
            btn_k_path.Enabled = true;
            if (lab_k_path.Text.Length > 0)
            {
                btn_k_generate.Enabled = true;
            }
        }

        private void btn_k_path_Click(object sender, EventArgs e)
        {
            var path = ChoosePath();
            if (path.Length > 0)
            {
                lab_k_path.Text = path;
            }

            if (txt_k_name.Text.Length != 0) btn_k_generate.Enabled = true;
        }

        private void btn_k_generate_Click(object sender, EventArgs e)
        {
            try
            {
                var fileName = $@"{lab_k_path.Text}\{txt_k_name.Text}.xlsx";
                var oldName = txt_k_old.Text;
                var newName = txt_k_new.Text;
                Log("开始统计考勤信息...");

                Dictionary<string, KTableData> users = new Dictionary<string, KTableData>();
                Log("开始统计老校区考勤信息...");
                ReadOldKUserData(oldName, users);
                Log("开始统计新校区考勤信息...");
                ReadNewKUserData(newName, users);
                Log("开始生成考勤统计表...");
                var kaoqinTable = GenerateKUserDataTable(users);
                Log("开始写入文件...");

                WriteKUserData(fileName, kaoqinTable);
                Log("考勤统计完成...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                ExcelManager.Close();
            }
        }

        private void WriteKUserData(string fileName, List<List<object>> table)
        {
            ExcelManager manager = new ExcelManager();
            manager.CreateWorkbook();
            Log("创建工作簿成功...");

            //写列标
            manager.SetRow(1, new List<object>()
            {
                "工号",
                "姓名",
                "新校区打卡天数",
                "老校区打卡天数",
                "是否全勤",
            });


            manager.SetRows(2, table);
            Log("写入考勤数据成功...");

            for (int i = 0; i < 5; i++) manager.SetColumnWidth(i + 1, 18);
            manager.SaveCopyAs(fileName);
            manager.CloseWorkbook();
            Log($"写入文件到{fileName}成功，关闭excel...");
            ExcelManager.Close();
        }

        private List<List<object>> GenerateKUserDataTable(Dictionary<string, KTableData> users)
        {
            var res = new List<List<object>>();
            foreach (var user in users.Values)
            {
                int newHit = 0;
                int oldHit = 0;
                foreach (var hit in user.HitCards)
                {
                    if (hit == HitCard.Old) oldHit++;
                    else if (hit == HitCard.New) newHit++;
                }

                string id = user.Id ?? "";
                string name = user.Name;
                bool isFull = false;
                if (newHit + oldHit >= nb_k_all.Value)
                {
                    if (ckb_k_key.Checked)
                    {
                        if (newHit >= nb_k_new.Value) isFull = true;
                    }
                    else
                    {
                        if (oldHit >= nb_k_old.Value) isFull = true;
                    }
                }

                string full = isFull ? "是" : "否";
                res.Add(new List<object>()
                {
                    id,
                    name,
                    newHit,
                    oldHit,
                    full
                });
            }

            return res;
        }

        private void Frm_Main_Load(object sender, EventArgs e)
        {
            fbd.SelectedPath = _desktopPath;
            txt_s_path.Text = _desktopPath;
            lab_k_path.Text = _desktopPath;
            lab_h_path.Text = _desktopPath;
            lab_r_path.Text = _desktopPath;
            grp_q_setting.Enabled = false;
        }

        private void btn_h_open_Click(object sender, EventArgs e)
        {
            var files = ChooseMultiFile("请选择考勤统计表");
            foreach (var file in files)
            {
                list_h_files.Items.Add(file);
            }

            if (list_h_files.Items.Count <= 0) return;
            btn_h_clearFiles.Enabled = true;
            btn_h_choosePath.Enabled = true;
            btn_h_generate.Enabled = true;
        }

        private void btn_h_clearFiles_Click(object sender, EventArgs e)
        {
            list_h_files.Items.Clear();
            btn_h_clearFiles.Enabled = false;
            btn_h_choosePath.Enabled = false;
            btn_h_generate.Enabled = false;
        }

        private void btn_h_choosePath_Click(object sender, EventArgs e)
        {
            lab_h_path.Text = ChooseSingleFile("请选择文件保存位置");
        }

        private void btn_h_generate_Click(object sender, EventArgs e)
        {
            try
            {
                Dictionary<string, HTableData> users = new Dictionary<string, HTableData>();
                int monthCount = 0;
                Log("开始汇总考勤统计表...");
                foreach (var item in list_h_files.Items)
                {
                    ReadHUserData(item.ToString(), users);
                    monthCount++;
                }

                var table = GenerateHUserDataTable(users, monthCount);
                string fileName = lab_h_path.Text + "\\" + txt_h_name.Text + ".xlsx";
                WriteHUserDataTable(fileName, table);
                Log("汇总考勤统计表完成...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Log("【任务异常中断】");
            }
            finally
            {
                ExcelManager.Close();
            }
        }

        private void ReadHUserData(string fileName, Dictionary<string, HTableData> users)
        {
            ExcelManager manager = new ExcelManager();
            manager.OpenWorkbook(fileName);
            Log($"打开工作簿{fileName}...");
            manager.OpenWorksheet(1);
            Log("开始读取数据，请耐心等待...");
            var cells = manager.GetAllData();
            Log("读取数据成功，开始分析数据...");
            const int initRow = 1;
            for (var i = initRow; i < cells.Length; i++)
            {
                var id = cells[i][0];
                var name = cells[i][1];
                var _new = Convert.ToInt32(cells[i][2]);
                var _old = Convert.ToInt32(cells[i][3]);
                var isFull = cells[i][4];
                if (users.ContainsKey(name))
                {
                    if (users[name].Id == null)
                    {
                        users[name].Id = id;
                    }

                    users[name].HitCounts.Add(_new);
                    users[name].HitCounts.Add(_old);
                    if (isFull == "是")
                    {
                        users[name].FullCounts++;
                    }
                }
                else
                {
                    var flag = 0;
                    if (isFull == "是") flag = 1;
                    users.Add(name, new HTableData()
                    {
                        Name = name,
                        Id = id,
                        HitCounts = new List<int>()
                        {
                            _new,
                            _old
                        },
                        FullCounts = flag
                    });
                }

                Log($"【{name}】新校区打卡次数【{_new}】，老校区打卡次数【{_old}】，是否全勤：【{isFull}】...");
            }

            manager.CloseWorkbook();
            Log("数据分析完成，关闭工作簿...");
            ExcelManager.Close();
        }

        private List<List<object>> GenerateHUserDataTable(Dictionary<string, HTableData> users, int monthCount)
        {
            Log("开始生成数据统计表...");
            var result = new List<List<object>>();
            var firstLine = new List<object>
            {
                "工号",
                "姓名"
            };
            for (int i = 0; i < monthCount; i++)
            {
                firstLine.Add($"第{i + 1}个月新校区打卡天数");
                firstLine.Add($"第{i + 1}个月老校区打卡天数");
            }

            firstLine.Add("全勤月数");
            firstLine.Add("新校区打卡补贴");
            firstLine.Add("老校区打卡补贴");
            result.Add(firstLine);

            int newM = Convert.ToInt32(nb_h_new.Value);
            int oldM = Convert.ToInt32(nb_h_old.Value);
            foreach (var user in users.Values)
            {
                var line = new List<object>
                {
                    user.Id,
                    user.Name
                };
                line.AddRange(user.HitCounts.Cast<object>());
                var flag = true;
                int newMoney = 0;
                int oldMoney = 0;
                foreach (var hit in user.HitCounts)
                {
                    //新校区
                    if (flag)
                    {
                        newMoney += hit * newM;
                    }
                    //老校区
                    else
                    {
                        oldMoney += hit * oldM;
                    }

                    flag = !flag;
                }

                line.Add(user.FullCounts);
                line.Add(newMoney);
                line.Add(oldMoney);
                result.Add(line);
            }

            Log("数据表生成成功...");
            return result;
        }

        private void WriteHUserDataTable(string fileName, List<List<object>> table)
        {
            Log("开始写入文件...");
            ExcelManager manager = new ExcelManager();
            manager.CreateWorkbook();
            Log("创建工作簿成功...");
            manager.SetRows(1, table);
            manager.SaveCopyAs(fileName);
            Log($"保存考勤汇总表到【{fileName}】成功...");
            manager.CloseWorkbook();
            Log("关闭工作簿...");
            ExcelManager.Close();
        }

        private void txt_s_name_TextChanged(object sender, EventArgs e)
        {
            if (list_s_files.Items.Count > 0)
            {
                btn_s_generate.Enabled = txt_s_name.Text.Length != 0;
            }
        }

        private void txt_k_name_TextChanged(object sender, EventArgs e)
        {
            if (txt_k_new.Text.Length > 0 && txt_k_old.Text.Length > 0)
            {
                btn_k_generate.Enabled = txt_k_name.Text.Length != 0;
            }
        }

        private void btn_r_bus_Click(object sender, EventArgs e)
        {
            var file = ChooseSingleFile("请选择校车统计表");
            if (file.Length > 0)
            {
                txt_r_bus.Text = file;
            }

            if (txt_r_bus.Text.Length > 0 && txt_r_kq.Text.Length > 0)
            {
                btn_r_generate.Enabled = true;
            }
        }

        private void btn_r_kq_Click(object sender, EventArgs e)
        {
            var file = ChooseSingleFile("请选择考勤统计表");
            if (file.Length > 0)
            {
                txt_r_kq.Text = file;
            }

            if (txt_r_bus.Text.Length > 0 && txt_r_kq.Text.Length > 0)
            {
                btn_r_generate.Enabled = true;
            }
        }

        private void btn_r_path_Click(object sender, EventArgs e)
        {
            var path = ChoosePath();
            if (path.Length > 0)
            {
                lab_r_path.Text = path;
            }
        }

        private void txt_r_name_TextChanged(object sender, EventArgs e)
        {
            if (txt_r_bus.Text.Length > 0 && txt_r_kq.Text.Length > 0)
            {
                btn_r_generate.Enabled = txt_r_name.Text.Length != 0;
            }
        }

        private void btn_r_generate_Click(object sender, EventArgs e)
        {
            try
            {
                var sName = txt_r_bus.Text;
                var kName = txt_r_kq.Text;
                var fileName = lab_r_path.Text + "\\" + txt_r_name.Text + ".xlsx";
                var fullMoney = Convert.ToInt32(nb_r_money.Value);
                Log("开始执行任务...");
                var users = new Dictionary<string, RTableData>();
                Log("开始读取校车统计表...");
                SetHTableDataS(sName, users);
                Log("开始读取考勤统计表...");
                SetHTableDataK(kName, users, fullMoney);
                Log("准备生成表格数据...");
                var table = GenerateRTableDataTable(users);
                Log("开始写入文件...");
                WriteRTableDataTable(fileName, table);
                Log("补贴汇总完成...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Log("【任务异常中断】");
            }
            finally
            {
                ExcelManager.Close();
            }
        }

        private void SetHTableDataS(string fileName, Dictionary<string, RTableData> users)
        {
            var manager = new ExcelManager();
            manager.OpenWorkbook(fileName);
            Log($"打开工作簿{fileName}成功...");
            manager.OpenWorksheet(1);
            Log("正在读取数据，请耐心等待...");
            var cells = manager.GetAllData();
            Log("读取数据成功，开始分析数据...");
            for (int i = 1; i < cells.Length; i++)
            {
                var id = cells[i][0];
                var name = cells[i][1];
                var money = int.Parse(cells[i][2]);
                if (users.ContainsKey(name))
                {
                    users[name].BusMoney = money;
                    if (users[name].Id == null)
                    {
                        users[name].Id = id;
                    }
                }
                else
                {
                    users.Add(name, new RTableData()
                    {
                        Id = id,
                        Name = name,
                        BusMoney = money
                    });
                }
            }

            Log("分析数据成功...");
            manager.CloseWorkbook();
            ExcelManager.Close();
        }

        private void SetHTableDataK(string fileName, Dictionary<string, RTableData> users, int fullMoneyPer)
        {
            var manager = new ExcelManager();
            manager.OpenWorkbook(fileName);
            Log($"打开工作簿{fileName}成功...");
            manager.OpenWorksheet(1);
            Log("开始读取数据，请耐心等待...");
            var col = manager.GetWorkSheetColumnsCount();
            var fullCounts = manager.GetColumnData(col - 3);
            var newMoneys = manager.GetColumnData(col - 2);
            var ids = manager.GetColumnData(0);
            var names = manager.GetColumnData(1);
            Log("读取数据成功，开始分析数据...");
            for (int i = 1; i < names.Length; i++)
            {
                var id = ids[i];
                var name = names[i];
                var fullCount = int.Parse(fullCounts[i]);
                var fullMoney = fullCount * fullMoneyPer;
                var newMoney = int.Parse(newMoneys[i]);
                if (users.ContainsKey(name))
                {
                    users[name].FullMoney = fullCount;
                    users[name].NewMoney = newMoney;
                    if (users[name].Id == null)
                    {
                        users[name].Id = id;
                    }
                }
                else
                {
                    users.Add(name, new RTableData()
                    {
                        Id = id,
                        Name = name,
                        FullCounts = fullCount,
                        NewMoney = newMoney,
                        FullMoney = fullMoney
                    });
                }
            }

            Log("分析数据成功...");
            manager.CloseWorkbook();
            Log("关闭工作簿...");
            ExcelManager.Close();
        }

        private List<List<object>> GenerateRTableDataTable(Dictionary<string, RTableData> users)
        {
            var res = new List<List<object>>();
            Log("正在生成表格数据...");
            res.Add(new List<object>()
            {
                "工号",
                "姓名",
                "校车补贴",
                "新校区打卡补贴",
                "老校区打卡补贴",
                "全勤月数",
                "全勤奖",
                "总计"
            });
            foreach (var user in users.Values)
            {
                user.CalculateMoney();
                res.Add(user.ToList());
            }

            Log("生成表格数据成功...");
            return res;
        }

        private void WriteRTableDataTable(string fileName, List<List<object>> table)
        {
            var manager = new ExcelManager();
            manager.CreateWorkbook();
            Log("创建工作簿成功...");
            Log("开始写入数据...");
            manager.SetRows(1, table);
            manager.SetColumnWidth(1, 16);
            Log("写入数据成功...");
            manager.SaveCopyAs(fileName);
            Log($"保存文件至{fileName}...");
            manager.CloseWorkbook();
            Log("关闭工作簿...");
            ExcelManager.Close();
        }

        private void btn_q_s_add_Click(object sender, EventArgs e)
        {
            var files = ChooseMultiFile("请选择校车记录文件");
            if (files.Length == 0)
            {
                return;
            }

            foreach (var file in files)
            {
                list_q_bus.Items.Add(file);
            }

            btn_q_s_clear.Enabled = true;
            btn_q_generate.Enabled = (list_q_bus.Items.Count != 0 && list_q_new.Items.Count != 0 &&
                                      list_q_new.Items.Count == list_q_old.Items.Count);
        }

        private void btn_q_s_clear_Click(object sender, EventArgs e)
        {
            list_q_bus.Items.Clear();
            btn_q_s_clear.Enabled = false;
            btn_q_generate.Enabled = false;
        }

        private void btn_q_k_addNew_Click(object sender, EventArgs e)
        {
            var files = ChooseMultiFile("请选择新校区打卡记录文件");
            if (files.Length == 0)
            {
                return;
            }

            foreach (var file in files)
            {
                list_q_new.Items.Add(file);
            }

            btn_q_k_removeNew.Enabled = true;
            btn_q_generate.Enabled = (list_q_bus.Items.Count != 0 && list_q_new.Items.Count != 0 &&
                                      list_q_new.Items.Count == list_q_old.Items.Count);
        }

        private void btn_q_k_removeNew_Click(object sender, EventArgs e)
        {
            list_q_new.Items.RemoveAt(list_q_new.Items.Count - 1);
            btn_q_k_removeNew.Enabled = list_q_new.Items.Count != 0;
            btn_q_generate.Enabled = (list_q_bus.Items.Count != 0 && list_q_new.Items.Count != 0 &&
                                      list_q_new.Items.Count == list_q_old.Items.Count);
        }

        private void btn_q_k_addOld_Click(object sender, EventArgs e)
        {
            var files = ChooseMultiFile("请选择老校区打卡记录文件");
            if (files.Length == 0)
            {
                return;
            }

            foreach (var file in files)
            {
                list_q_old.Items.Add(file);
            }

            btn_q_k_removeOld.Enabled = true;
            btn_q_generate.Enabled = (list_q_bus.Items.Count != 0 && list_q_new.Items.Count != 0 &&
                                      list_q_new.Items.Count == list_q_old.Items.Count);
        }

        private void btn_q_k_removeOld_Click(object sender, EventArgs e)
        {
            list_q_old.Items.RemoveAt(list_q_old.Items.Count - 1);
            btn_q_k_removeOld.Enabled = list_q_old.Items.Count != 0;
            btn_q_generate.Enabled = (list_q_bus.Items.Count != 0 && list_q_new.Items.Count != 0 &&
                                      list_q_new.Items.Count == list_q_old.Items.Count);
        }

        private void nb_q_new_ValueChanged(object sender, EventArgs e)
        {
            nb_k_new.Value = nb_q_new.Value;
        }

        private void nb_q_old_ValueChanged(object sender, EventArgs e)
        {
            nb_k_old.Value = nb_q_old.Value;
        }

        private void nb_q_all_ValueChanged(object sender, EventArgs e)
        {
            nb_k_all.Value = nb_q_all.Value;
        }

        private void ckb_q_key_CheckedChanged(object sender, EventArgs e)
        {
            nb_k_new.Enabled = !nb_k_new.Enabled;
            nb_k_old.Enabled = !nb_k_old.Enabled;
            nb_q_new.Enabled = nb_k_new.Enabled;
            nb_q_old.Enabled = nb_k_old.Enabled;
            ckb_k_key.Checked = ckb_q_key.Checked;
        }

        private void nb_k_new_ValueChanged(object sender, EventArgs e)
        {
            nb_q_new.Value = nb_k_new.Value;
        }

        private void nb_k_old_ValueChanged(object sender, EventArgs e)
        {
            nb_q_old.Value = nb_k_old.Value;
        }

        private void nb_k_all_ValueChanged(object sender, EventArgs e)
        {
            nb_q_all.Value = nb_k_all.Value;
        }

        private int p_index = 0;

        private void btn_q_generate_Click(object sender, EventArgs e)
        {
            try
            {
                var res = MessageBox.Show("本软件在统计过程中将会关闭后台所有的EXCEL程序，请确认您已保存当前您所有已打开的EXCEL文件之后，再执行此操作！\n" +
                                          "是否继续执行生成统计表操作？", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (res != DialogResult.Yes) return;
                btn_q_generate.Enabled = false;
                if (!Directory.Exists(_filePath))
                {
                    Log("创建任务文件夹成功...");
                    Directory.CreateDirectory(_filePath);
                }

                Log($"在任务执行过程中，请一定不要对【{DirName}】文件夹做任何操作，否则将会导致任务失败！");
                Log("开始执行...");
                //设置车贴统计页面属性
                list_s_files.Items.Clear();
                list_s_files.Items.AddRange(list_q_bus.Items);
                txt_s_path.Text = _filePath;
                //设置考勤统计>单月统计页面属性
                lab_k_path.Text = _filePath;
                //设置考勤统计>考勤汇总页面属性
                lab_h_path.Text = _filePath;
                //设置补贴汇总页面属性
                txt_r_bus.Text = $@"{_filePath}\{txt_s_name.Text}.xlsx";
                txt_r_kq.Text = $@"{_filePath}\{txt_h_name.Text}.xlsx";
                lab_r_path.Text = _filePath;

                //开始统计校车考勤
                btn_s_generate_Click(sender, e);
                Log("校车费用统计完成，准备统计考勤记录...");
                var str =
                    $"当前第{p_index + 1}张考勤表的全勤选项被设置为新校区打卡【{nb_q_new.Value}】次，总共打卡【{nb_q_all.Value}】次，无改动则默认即可，设置完成请点击继续执行...";
                Log(str);
                MessageBox.Show(str);
                btn_q_continue.Enabled = true;
                grp_q_setting.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Log("【任务异常中断】");
            }
            finally
            {
                ExcelManager.Close();
            }
        }

        private int taskIndex = 0;

        private void btn_q_continue_Click(object sender, EventArgs e)
        {
            btn_q_continue.Enabled = false;
            grp_q_setting.Enabled = false;
            switch (taskIndex)
            {
                case 0:
                {
                    SingleMonthKq(sender, e);
                    Log($"【{txt_k_name.Text}_{p_index + 1}】统计完成...");
                    //如果还有未统计的考勤表
                    if (p_index < list_q_new.Items.Count)
                    {
                        var str1 =
                            $"当前{p_index + 1}考勤表的全勤选项被设置为新校区打卡【{nb_q_new.Value}】次，总共打卡【{nb_q_all.Value}】次，无改动则默认即可。设置完成后，请返回快速统计页面点击继续执行...";
                        Log(str1);
                        MessageBox.Show(str1);
                        btn_q_continue.Enabled = true;
                        grp_q_setting.Enabled = true;
                    }
                    else
                    {
                        Log("考勤统计表全部统计完成...");
                        Log("准备合并考勤信息统计表...");
                        var str2 =
                            $"当前新校区补贴被设为【{nb_h_new.Value}】元/次，如有改动请于【{tab_kq.Text}>{tab_merge_kq.Text}】页面进行设置。\n设置完成后，请返回快速统计页面点击继续执行。";
                        Log(str2);
                        MessageBox.Show(str2);
                        btn_q_continue.Enabled = true;
                        taskIndex = 1;
                    }

                    break;
                }
                case 1:
                {
                    Log("开始合并考勤信息...");
                    btn_h_generate_Click(sender, e);
                    Log("合并考勤信息完成，准备合并校车补贴与考勤补贴...");
                    var str3 =
                        $"当前每月全勤奖被设置为【{nb_r_money.Value}】元/月，如若更改请于【{tab_merge.Text}】页面进行设置。\n设置完成后，请返回快速统计页面点击继续执行...";
                    Log(str3);
                    MessageBox.Show(str3);
                    taskIndex = 2;
                    btn_q_continue.Enabled = true;
                    break;
                }
                case 2:
                    btn_r_generate_Click(sender, e);
                    Log("所有任务均已完成...");
                    var str4 = $"请在桌面上【{DirName}】文件夹查看...";
                    Log(str4);
                    MessageBox.Show(str4);
                    taskIndex = 5;
                    break;
            }
        }

        /// <summary>
        /// 单月考勤统计
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SingleMonthKq(object sender, EventArgs e)
        {
            txt_k_new.Text = list_q_new.Items[p_index].ToString();
            txt_k_old.Text = list_q_old.Items[p_index].ToString();
            Log($"正在处理【{txt_k_new.Text}】和【{txt_k_old.Text}】...");
            //动态设置单月考勤统计表名称
            txt_k_name.Text = $@"单月考勤表_{p_index + 1}";
            //向考勤汇总页面添加文件
            list_h_files.Items.Add($@"{lab_k_path.Text}\{txt_k_name.Text}.xlsx");
            p_index++;
            btn_k_generate_Click(sender, e);
        }

        private void lab_about_Click(object sender, EventArgs e)
        {
            new Frm_About().Show();
        }
    }
}